home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 November: Tool Chest / Dev.CD Nov 96 TC / Dev.CD Nov 96 TC.toast / What's New? / Development Kits / Apple Game Sprockets / DrawSprocket 1.0 / DrawSprocketTest Sources / DrawSprocketTest.c
Encoding:
C/C++ Source or Header  |  1996-09-12  |  41.5 KB  |  1,515 lines  |  [TEXT/CWIE]

  1. /*
  2. ********************************************************************************
  3. **
  4. ** Name: DrawSprocketTest.c
  5. **
  6. ** Description:
  7. **
  8. **    Simple console window application to test the functionality of
  9. **    DrawSprocket.  This application does operations that one would not
  10. **    normally do when using DrawSprocket in a game, for example providing
  11. **    bogus input parameters.
  12. **
  13. ********************************************************************************
  14. **
  15. ** Revision History
  16. **
  17. ** 23-Apr-96    CF    Converted to final DS naming.
  18. **
  19. ********************************************************************************
  20. */
  21. #include <Quickdraw.h>
  22. #include <Events.h>
  23. #include <Fonts.h>
  24. #include <Memory.h>
  25. #include <Windows.h>
  26. #include <Menus.h>
  27. #include <TextEdit.h>
  28. #include <Dialogs.h>
  29. #include <Displays.h>
  30.  
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <math.h>
  35. #include <sioux.h>
  36.  
  37. #include "DrawSprocket.h"
  38.  
  39. /*
  40. ********************************************************************************
  41. ** constants
  42. ********************************************************************************
  43. */
  44. #define kRectSize 16
  45.  
  46. /*
  47. ********************************************************************************
  48. ** globals
  49. ********************************************************************************
  50. */
  51. UInt32 gVBLSync = 1;
  52. char gTextBuffer[512];
  53.  
  54. /*
  55. ********************************************************************************
  56. ** prototypes
  57. ********************************************************************************
  58. */
  59. void main( void );
  60. void ErrorMessage( char *inMessage, OSStatus inError );
  61. void DumpContextAttributes( DSpContextAttributes *inAttributes );
  62. void MyInitAttributes( DSpContextAttributes *inAttributes );
  63.  
  64. void TestDrawSprocket( void );
  65. void TestContextIteration( void );
  66. void TestContextSearchingAuto( void );
  67. void TestContextSearchingManual( void );
  68. void TestContextBuffering( Boolean inUseUnderlay, Boolean inUseOverlay,
  69.             Boolean inUseScaling, Boolean inUseSingleBuffer );
  70. void TestContextCLUT( void );
  71. void TestUserSelectContext( void );
  72.  
  73. /*
  74. ********************************************************************************
  75. ** support routines
  76. ********************************************************************************
  77. */
  78. #pragma mark ##### support routines #####
  79.  
  80. /*
  81. ********************************************************************************
  82. **
  83. ** Name: main
  84. **
  85. ** Description:
  86. **
  87. **    Program entry point.  Starts up and shuts down DrawSprocket.
  88. **
  89. ********************************************************************************
  90. */
  91. void
  92. main( void )
  93. {
  94.     OSStatus theError;
  95.     
  96.     /* tell SIOUX to shut up */
  97.     SIOUXSettings.autocloseonquit = true;
  98.     SIOUXSettings.asktosaveonclose = false;
  99.     
  100.     /* startup DrawSprocket */
  101.     theError = DSpStartup();
  102.     if( theError )
  103.     {
  104.         ErrorMessage( "DSpStartup()", theError );
  105.         return;
  106.     }
  107.     
  108.     /* main test menu */
  109.     TestDrawSprocket();
  110.     
  111.     /* shutdown draw sprocket */
  112.     theError = DSpShutdown();
  113.     if( theError )
  114.         ErrorMessage( "DSpShutdown()", theError );
  115.  
  116. }
  117.  
  118. /*
  119. ********************************************************************************
  120. **
  121. ** Name: ErrorMessage
  122. **
  123. ** Description:
  124. **
  125. **    Prints an error message in human-readable form.
  126. **
  127. ********************************************************************************
  128. */
  129. void
  130. ErrorMessage(
  131.     char *inMessage,    /* message to display with error code        */
  132.     OSStatus inError    /* error code                                */
  133. )
  134. {
  135.     UInt32 theIndex;
  136.     static char *theErrorTexts[] = {
  137.         "Unknown Error",
  138.         "kDSpNotInitializedErr",
  139.         "kDSpSystemSWTooOldErr",
  140.         "kDSpInvalidContextErr",
  141.         "kDSpInvalidAttributesErr",
  142.         "kDSpContextAlreadyReservedErr",
  143.         "kDSpContextNotReservedErr",
  144.         "kDSpContextNotFoundErr",
  145.         "kDSpFrameRateNotReadyErr",
  146.         "kDSpConfirmSwitchWarning",
  147.         "kDSpInternalErr"
  148.     };
  149.     
  150.     /* convert the error code into an array index */    
  151.     if( inError <= kDSpNotInitializedErr &&
  152.         inError >= kDSpInternalErr )
  153.     {
  154.         theIndex = kDSpNotInitializedErr - inError + 1;
  155.     }
  156.     else
  157.         theIndex = 0;
  158.     
  159.     /* print the message */
  160.     printf("# Error %d (%s) encountered: %s\n", inError,
  161.         theErrorTexts[theIndex], inMessage );
  162.     
  163.     return;
  164. }
  165.  
  166. /*
  167. ********************************************************************************
  168. **
  169. ** Name: DumpContextAttributes
  170. **
  171. ** Description:
  172. **
  173. **    Display the contents of a DSpContextAttributes structure.
  174. **
  175. ********************************************************************************
  176. */
  177. void
  178. DumpContextAttributes(
  179.     DSpContextAttributes *inAttributes        /* attributes to show */
  180. )
  181. {
  182.     printf("\t             frequency : ");
  183.     if( inAttributes->frequency )
  184.         printf( "%dhz\n", inAttributes->frequency>>16 );
  185.     else
  186.         printf( "(unknown)\n" );
  187.     printf("\t          displayWidth : %d\n", inAttributes->displayWidth );
  188.     printf("\t         displayHeight : %d\n", inAttributes->displayHeight );
  189.     
  190.     printf("\t            colorNeeds : ");
  191.     switch( inAttributes->colorNeeds )
  192.     {
  193.         case kDSpColorNeeds_DontCare:
  194.             printf("kDSpColorNeeds_DontCare\n");
  195.             break;
  196.     
  197.         case kDSpColorNeeds_Request:
  198.             printf("kDSpColorNeeds_Request\n");
  199.             break;
  200.     
  201.         case kDSpColorNeeds_Require:
  202.             printf("kDSpColorNeeds_Require\n");
  203.             break;
  204.     
  205.         default:
  206.             printf(" %d (Unknown)\n", inAttributes->colorNeeds );
  207.             break;
  208.     }
  209.     
  210.     printf("\t            colorTable : 0x%X\n", inAttributes->colorTable );
  211.     
  212.     printf("\t        contextOptions : \n");
  213.     if( inAttributes->contextOptions & kDSpContextOption_QD3DAccel )
  214.         printf("\t                         kDSpContextOption_QD3DAccel\n");
  215.     if( inAttributes->contextOptions & kDSpContextOption_PageFlip )
  216.         printf("\t                         kDSpContextOption_PageFlip\n");
  217.     if( 0 == inAttributes->contextOptions )
  218.         printf("\t                     (no options set)\n");
  219.         
  220.     printf("\t   backBufferDepthMask : 0x%X\n", inAttributes->backBufferDepthMask );
  221.     printf("\t      displayDepthMask : 0x%X\n", inAttributes->displayDepthMask );
  222.     printf("\t   backBufferBestDepth : %d\n", inAttributes->backBufferBestDepth );
  223.     printf("\t      displayBestDepth : %d\n", inAttributes->displayBestDepth );
  224.     printf("\t             pageCount : %d\n", inAttributes->pageCount );
  225.     
  226.     printf("\t gameMustConfirmSwitch : ");
  227.     if( inAttributes->gameMustConfirmSwitch )
  228.         printf("TRUE\n");
  229.     else
  230.         printf("FALSE\n");
  231. }
  232.  
  233. /*
  234. ********************************************************************************
  235. **
  236. ** Name: MyInitAttributes
  237. **
  238. ** Description:
  239. **
  240. **    Initialize a context attributes structure so that there is no garbage
  241. **    data in it.  This is important to do because DS will return an error
  242. **    if some fields are set incorrectly (including the "reserved" fields not
  243. **    being set to zero), and some things can actually cause a crash (such
  244. **    as a bogus color table handle).
  245. **
  246. ********************************************************************************
  247. */
  248. void
  249. MyInitAttributes(
  250.     DSpContextAttributes *inAttributes        /* attr structure to init */
  251. )
  252. {
  253.     if( NULL == inAttributes )
  254.         DebugStr("\pStimpy! You Idiot!");
  255.         
  256.     inAttributes->frequency                    = 0;
  257.     inAttributes->displayWidth                = 0;
  258.     inAttributes->displayHeight                = 0;
  259.     inAttributes->reserved1                    = 0;
  260.     inAttributes->reserved2                    = 0;
  261.     inAttributes->colorNeeds                = 0;
  262.     inAttributes->colorTable                = NULL;
  263.     inAttributes->contextOptions            = 0;
  264.     inAttributes->backBufferDepthMask        = 0;
  265.     inAttributes->displayDepthMask            = 0;
  266.     inAttributes->backBufferBestDepth        = 0;
  267.     inAttributes->displayBestDepth            = 0;
  268.     inAttributes->pageCount                    = 0;
  269.     inAttributes->gameMustConfirmSwitch        = false;
  270.     inAttributes->reserved3[0]                = 0;
  271.     inAttributes->reserved3[1]                = 0;
  272.     inAttributes->reserved3[2]                = 0;
  273.     inAttributes->reserved3[3]                = 0;
  274. }
  275.  
  276. /*
  277. ********************************************************************************
  278. ** test routines
  279. ********************************************************************************
  280. */
  281. #pragma mark ##### test routines #####
  282.  
  283. /*
  284. ********************************************************************************
  285. **
  286. ** Name: TestDrawSprocket
  287. **
  288. ** Description:
  289. **
  290. **    Main test dispatcher for the DrawSprocket test routines.
  291. **
  292. ********************************************************************************
  293. */
  294. void
  295. TestDrawSprocket( void )
  296. {
  297.     Boolean theDoneFlag = false;
  298.     
  299.     while( false == theDoneFlag )
  300.     {
  301.         UInt32 theChoice;
  302.         
  303.         printf("\n\n############################################################\n");
  304.         printf("DrawSprocket test application.\n");
  305.         printf("Please select from the following tests:\n");        
  306.         
  307.         printf("\t 1. Exit\n");
  308. //        printf("\t 2. Run all tests automatically\n");
  309. //        printf("\t 3. Dump information needed for DrawSprocket bug reports\n");
  310.         printf("\t 4. Display/context iteration\n");
  311.         printf("\t 5. Context searching (auto selection of w/h/d/d)\n");
  312.         printf("\t 6. Context searching (you specify w/h/d/d)\n");
  313.         printf("\t 7. Multiple-buffering/page flipping (640x480x8)\n");
  314.         printf("\t 8. CLUT operations\n");
  315.         printf("\t 9. DSpUserSelectContext\n");
  316.         printf("\t10. Underlays\n");
  317. //        printf("\t11. Overlays\n");
  318. //        printf("\t12. Overlays & Underlays\n");
  319. //        printf("\t13. Pixel Scaling\n");
  320.         printf("\t14. Single Buffering\n");
  321.         if( gVBLSync )
  322.             printf("\t15. Disable VBL Sync\n");
  323.         else
  324.             printf("\t15. Enable VBL Sync\n");
  325.         
  326.         printf("\n\tSelection: ");
  327.         gets( gTextBuffer );
  328.         theChoice = atoi( gTextBuffer );
  329.         switch( theChoice )
  330.         {
  331.             /* exit */
  332.             case 1:
  333.                 theDoneFlag = true;
  334.                 break;
  335.                 
  336.             /* context iteration */
  337.             case 4:
  338.                 TestContextIteration();
  339.                 break;            
  340.             
  341.             /* auto context searching */
  342.             case 5:
  343.                 TestContextSearchingAuto();
  344.                 break;
  345.  
  346.             /* manual context searching */
  347.             case 6:
  348.                 TestContextSearchingManual();
  349.                 break;
  350.                 
  351.             /* buffering */
  352.             case 7:
  353.                 TestContextBuffering( false, false, false, false );
  354.                 break;
  355.             
  356.             /* CLUT */
  357.             case 8:
  358.                 TestContextCLUT();
  359.                 break;
  360.             
  361.             /* user select context */
  362.             case 9:
  363.                 TestUserSelectContext();
  364.                 break;
  365.                         
  366.             /* underlay */
  367.             case 10:
  368.                 TestContextBuffering( true, false, false, false );
  369.                 break;
  370.             
  371.             /* overlay */
  372.             case 11:
  373.                 TestContextBuffering( false, true, false, false );
  374.                 break;
  375.             
  376.             /* overlay & underlay */
  377.             case 12:
  378.                 TestContextBuffering( true, true, false, false );
  379.                 break;
  380.             
  381.             /* overlay & underlay & scaling */
  382.             case 13:
  383.                 TestContextBuffering( true, true, true, false );
  384.                 break;
  385.             
  386.             /* single buffer */
  387.             case 14:
  388.                 TestContextBuffering( false, false, false, true );
  389.                 break;
  390.                 
  391.             /* toggle sync */
  392.             case 15:
  393.                 gVBLSync ^= 1;
  394.                 break;
  395.                 
  396.             /* unknown */
  397.             default:
  398.                 printf("\nhuh?\n");
  399.                 break;            
  400.         }
  401.         
  402.         printf("\nThank you, please drive through.\n");
  403.     }
  404. }
  405.  
  406. /*
  407. ********************************************************************************
  408. **
  409. ** Name: TestContextIteration
  410. **
  411. ** Description:
  412. **
  413. **    Test the ability of DrawSprocket to iterate through the available
  414. **    display devices and contexts.
  415. **
  416. ********************************************************************************
  417. */
  418. void
  419. TestContextIteration( void )
  420. {
  421.     GDHandle theGDevice;
  422.     OSStatus theError;
  423.     
  424.     printf("\n\n");
  425.     printf("############################################################\n");
  426.     printf("###          Testing Display/Context Iteration           ###\n");
  427.     printf("############################################################\n");
  428.     printf("\n\n");
  429.  
  430.     /*
  431.     ** Walk the list of display devices in the system.  DrawSprocket is
  432.     ** centered around the DisplayIDType, which is used by the Display
  433.     ** Manager.  The GDevice records are going to be in flux with future
  434.     ** versions of the system software, so it is best to make the change
  435.     ** now and make your software DisplayManager-centric.
  436.     */
  437.     theGDevice = DMGetFirstScreenDevice( false );
  438.     while( theGDevice )
  439.     {
  440.         DisplayIDType theDisplayID;
  441.         DSpContextReference theContext;
  442.         UInt32 theContextIndex = 0;
  443.         
  444.         /* get the display ID */
  445.         theError = DMGetDisplayIDByGDevice( theGDevice, &theDisplayID,
  446.             false );
  447.         if( theError )
  448.         {
  449.             ErrorMessage( "DMGetDisplayIDByGDevice", theError );
  450.             return;
  451.         }
  452.         
  453.         /* walk the list of contexts for this display */
  454.         theError = DSpGetFirstContext( theDisplayID, &theContext );
  455.         while( noErr == theError )
  456.         {
  457.             DSpContextAttributes theAttributes;
  458.             
  459.             /* obtain the context attributes */
  460.             theError = DSpContext_GetAttributes( theContext, &theAttributes );
  461.             if( theError )
  462.             {
  463.                 ErrorMessage( "DSpContext_GetAttributes", theError );
  464.                 return;
  465.             }
  466.             
  467.             /* display the attributes structure */
  468.             printf("Display %d, Context %d capabilities:\n", theDisplayID,
  469.                 theContextIndex++ );
  470.             DumpContextAttributes( &theAttributes );
  471.  
  472.             /*
  473.             ** get the next context.  when a kDSpContextNotFoundErr code
  474.             ** is returned we have hit the end of the context list.  if
  475.             ** a different error code is returned, something went wrong.
  476.             */
  477.             theError = DSpGetNextContext( theContext, &theContext );
  478.             if( theError && ( kDSpContextNotFoundErr != theError ) )
  479.             {
  480.                 ErrorMessage( "DSpGetNextContext", theError );
  481.                 return;
  482.             }
  483.         }
  484.  
  485.         /* next device */
  486.         theGDevice = DMGetNextScreenDevice( theGDevice, false );
  487.     }    
  488. }
  489.  
  490. /*
  491. ********************************************************************************
  492. **
  493. ** Name: TestContextSearchingAuto
  494. **
  495. ** Description:
  496. **
  497. **    Test the ability of DrawSprocket to find a context that matches
  498. **    the requested attributes.
  499. **
  500. ********************************************************************************
  501. */
  502. void TestContextSearchingAuto( void )
  503. {
  504.     DSpContextAttributes theDesiredAttributes;
  505.     DSpContextReference theContext;
  506.     OSStatus theError;
  507.     
  508.     printf("\n\n");
  509.     printf("############################################################\n");
  510.     printf("###          Testing Display/Context Searching           ###\n");
  511.     printf("############################################################\n");
  512.     printf("\n\n");
  513.  
  514.     /*
  515.     ** Find a 320x200x8 mode
  516.     **
  517.     ** First, init the attributes so that there will be no garbage in any
  518.     ** of the fields (and which will cause DS to return an error).  This
  519.     ** is especially important for fields that DS can't check, such as
  520.     ** the colorTable.  If the colorTable is bogus when a call to reserve
  521.     ** a context is made, then it will try to use the bogus color table
  522.     ** (causing unpleasant visits to the debugger).
  523.     **
  524.     ** When using DSpFindBestContext(), the attributes are interpreted as
  525.     ** *REQUIREMENTS*, unlike when you call DSpContext_Reserve(), when
  526.     ** they are interpreted as *REQUESTS*.  If I specify a contextOption
  527.     ** of kDSpContextOption_PageFlip here, only contexts with the ability
  528.     ** to page flip will be considered in the search, however if I specify
  529.     ** the same option when reserving the context, and page flipping is not
  530.     ** available, then DS will use software double/triple buffering.  This
  531.     ** is so to make it easy for the game to always request that DS use
  532.     ** page flipping if it is there (at reservation time), but still continue
  533.     ** if it is not.  Conversely, the game can search for only contexts
  534.     ** that meet a specific criteria, and know that any matches found will
  535.     ** meet those specifications.
  536.     */
  537.     MyInitAttributes( &theDesiredAttributes );
  538.     theDesiredAttributes.displayWidth            = 320;
  539.     theDesiredAttributes.displayHeight            = 200;
  540.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  541.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  542.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  543.     theDesiredAttributes.backBufferBestDepth    = 8;
  544.     theDesiredAttributes.displayBestDepth        = 8;
  545.     theDesiredAttributes.pageCount                = 2;
  546.     theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
  547.     if( theError && kDSpContextNotFoundErr != theError )
  548.     {
  549.         ErrorMessage( "DSpFindBestContext 320x200x8", theError );
  550.         return;
  551.     }
  552.     if( kDSpContextNotFoundErr == theError )
  553.     {
  554.         printf("# Unable to find a matching context for the following attributes:\n");
  555.         DumpContextAttributes( &theDesiredAttributes );
  556.         return;
  557.     }
  558.     else
  559.     {
  560.         DSpContextAttributes theActualAttributes;
  561.         DisplayIDType theDisplayID;
  562.         
  563.         /* get the actual attributes for the context */
  564.         theError = DSpContext_GetAttributes( theContext, &theActualAttributes );
  565.         if( theError )
  566.         {
  567.             ErrorMessage( "DSpContext_GetAttributes", theError );
  568.             return;
  569.         }
  570.  
  571.         /* get the display id for the context */
  572.         theError = DSpContext_GetDisplayID( theContext, &theDisplayID );
  573.         if( theError )
  574.         {
  575.             ErrorMessage( "DSpContext_GetDisplayID", theError );
  576.             return;
  577.         }
  578.  
  579.         /* tell the user about the results */
  580.         printf("Best matching Context for the following attributes...\n");
  581.         DumpContextAttributes( &theDesiredAttributes );
  582.  
  583.         printf("...is the context on display id %d with these attributes:\n",
  584.             theDisplayID );
  585.         DumpContextAttributes( &theActualAttributes );
  586.     }
  587. }
  588.  
  589. /*
  590. ********************************************************************************
  591. **
  592. ** Name: TestContextSearchingManual
  593. **
  594. ** Description:
  595. **
  596. **    Test the ability of DrawSprocket to find a context that matches
  597. **    the requested attributes, but let the user choose the attributes.
  598. **
  599. ********************************************************************************
  600. */
  601. void TestContextSearchingManual( void )
  602. {
  603.     DSpContextAttributes theDesiredAttributes;
  604.     DSpContextReference theContext;
  605.     OSStatus theError;
  606.     
  607.     printf("\n\n");
  608.     printf("############################################################\n");
  609.     printf("###          Testing Display/Context Searching           ###\n");
  610.     printf("############################################################\n");
  611.     printf("\n\n");
  612.  
  613.     /* get the context attributes */
  614.     MyInitAttributes( &theDesiredAttributes );
  615.     theDesiredAttributes.pageCount                = 2;
  616.  
  617.     printf("enter the display width: ");
  618.     gets(gTextBuffer);
  619.     theDesiredAttributes.displayWidth            = atoi(gTextBuffer);
  620.     if( 0 == theDesiredAttributes.displayWidth )
  621.     {
  622.         printf("bogus value!\n");
  623.         return;
  624.     }
  625.     
  626.     printf("enter the display height: ");
  627.     gets(gTextBuffer);
  628.     theDesiredAttributes.displayHeight            = atoi(gTextBuffer);
  629.     if( 0 == theDesiredAttributes.displayHeight )
  630.     {
  631.         printf("bogus value!\n");
  632.         return;
  633.     }
  634.     
  635.     printf("enter the back buffer best depth: ");
  636.     gets(gTextBuffer);
  637.     theDesiredAttributes.backBufferBestDepth    = atoi(gTextBuffer);
  638.     if( 0 == theDesiredAttributes.backBufferBestDepth )
  639.     {
  640.         printf("bogus value!\n");
  641.         return;
  642.     }
  643.     
  644.     printf("enter the display best depth: ");
  645.     gets(gTextBuffer);
  646.     theDesiredAttributes.displayBestDepth        = atoi(gTextBuffer);
  647.     if( 0 == theDesiredAttributes.displayBestDepth )
  648.     {
  649.         printf("bogus value!\n");
  650.         return;
  651.     }
  652.     
  653.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  654.     theDesiredAttributes.backBufferDepthMask    = theDesiredAttributes.backBufferBestDepth;
  655.     theDesiredAttributes.displayDepthMask        = theDesiredAttributes.displayBestDepth;
  656.  
  657.     /* find the context */
  658.     theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
  659.     if( theError && kDSpContextNotFoundErr != theError )
  660.     {
  661.         ErrorMessage( "DSpFindBestContext (Manual)", theError );
  662.         return;
  663.     }
  664.     if( kDSpContextNotFoundErr == theError )
  665.     {
  666.         printf("# Unable to find a matching context for the following attributes:\n");
  667.         DumpContextAttributes( &theDesiredAttributes );
  668.         return;
  669.     }
  670.     else
  671.     {
  672.         DSpContextAttributes theActualAttributes;
  673.         DisplayIDType theDisplayID;
  674.         
  675.         /* get the actual attributes for the context */
  676.         theError = DSpContext_GetAttributes( theContext, &theActualAttributes );
  677.         if( theError )
  678.         {
  679.             ErrorMessage( "DSpContext_GetAttributes", theError );
  680.             return;
  681.         }
  682.  
  683.         /* get the display id for the context */
  684.         theError = DSpContext_GetDisplayID( theContext, &theDisplayID );
  685.         if( theError )
  686.         {
  687.             ErrorMessage( "DSpContext_GetDisplayID", theError );
  688.             return;
  689.         }
  690.  
  691.         /* tell the user about the results */
  692.         printf("Best matching Context for the following attributes...\n");
  693.         DumpContextAttributes( &theDesiredAttributes );
  694.  
  695.         printf("...is the context on display id %d with these attributes:\n",
  696.             theDisplayID );
  697.         DumpContextAttributes( &theActualAttributes );
  698.     }
  699. }
  700.  
  701. /*
  702. ********************************************************************************
  703. **
  704. ** Name: TestContextBuffering
  705. **
  706. ** Description:
  707. **
  708. **    Test the ability of DrawSprocket to sw buffer or page flip an image.
  709. **
  710. ********************************************************************************
  711. */
  712. void TestContextBuffering(
  713.     Boolean inUseUnderlay,
  714.     Boolean inUseOverlay,
  715.     Boolean inUseScaling,
  716.     Boolean inUseSingleBuffer
  717. )
  718. {
  719.     DSpContextAttributes theDesiredAttributes;
  720.     DSpContextReference theContext;
  721.     OSStatus theError;
  722.     DSpAltBufferReference theUnderlay, theOverlay;
  723.     UInt32 theDisplayWidth, theDisplayHeight;
  724.     
  725.     printf("\n\n");
  726.     printf("############################################################\n");
  727.     printf("###                  Testing Buffering                   ###\n");
  728.     printf("############################################################\n");
  729.     printf("\n\n");
  730.  
  731.  
  732.     /* find the context */
  733.     MyInitAttributes( &theDesiredAttributes );
  734.     theDesiredAttributes.displayWidth            = 640;
  735.     theDesiredAttributes.displayHeight            = 480;
  736.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  737.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  738.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  739.     theDesiredAttributes.backBufferBestDepth    = 8;
  740.     theDesiredAttributes.displayBestDepth        = 8;
  741.     theDesiredAttributes.pageCount                = 2;
  742.     if( inUseSingleBuffer )
  743.         theDesiredAttributes.pageCount            = 1;
  744.     theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
  745.     if( theError && kDSpContextNotFoundErr != theError )
  746.     {
  747.         ErrorMessage( "DSpFindBestContext", theError );
  748.         return;
  749.     }
  750.     if( kDSpContextNotFoundErr == theError )
  751.     {
  752.         printf("# Unable to find a matching context for the following attributes:\n");
  753.         DumpContextAttributes( &theDesiredAttributes );
  754.         return;
  755.     }
  756.  
  757.     theDisplayWidth = 640;
  758.     theDisplayHeight = 480;
  759.     
  760.     /*
  761.     ** Here is where I need to OR in the value to use page flipping.  If
  762.     ** I had used the value when calling DSpFindBestContext() then it would
  763.     ** have only considered displays that have page flipping hardware, but
  764.     ** I want to run with software buffering too.
  765.     */
  766.     theDesiredAttributes.contextOptions |= kDSpContextOption_PageFlip;
  767.  
  768.     /*
  769.     ** If page flipping isn't available, then software buffering will
  770.     ** be used.  DS can use double or triple buffering depending on the
  771.     ** state of the kDSpContextOption_TripleBuffer option bit.
  772.     **
  773.     ** If you only want double buffering, perhaps because of memory
  774.     ** constraints (a certain person named BG comes to mind, don't
  775.     ** go postal on me BG :-), then you should turn off the option bit.
  776.     **
  777.     ** If you leave the bit on and there is hardware page flipping
  778.     ** available (and you haven't turned off that option bit), but
  779.     ** there are only 2 video pages (not three) then DS will consider
  780.     ** page flipping to be more important of an option than triple
  781.     ** buffering and will drop you down to 2 VRAM pages (leaving you
  782.     ** still page flipping).
  783.     **
  784.     */
  785.     /*
  786.     theDesiredAttributes.contextOptions &= ~kDSpContextOption_TripleBuffer;
  787.     */
  788.  
  789.     /*
  790.     ** set vbl sync
  791.     */
  792.     if( false == gVBLSync )
  793.         theDesiredAttributes.contextOptions |= kDSpContextOption_DontSyncVBL;
  794.             
  795.     /* reserve the context */    
  796.     theError = DSpContext_Reserve( theContext, &theDesiredAttributes );
  797.     if( theError )
  798.     {
  799.         ErrorMessage( "DSpContext_Reserve", theError );
  800.         return;
  801.     }
  802.     
  803. #if 0
  804.     if( inUseScaling )
  805.     {
  806.         theError = DSpContext_SetScale( theContext, kDSpBufferScale_2 );
  807.         if( theError )
  808.         {
  809.             ErrorMessage( "DSpContext_SetScale", theError );
  810.             return;
  811.         }
  812.         
  813.         theDisplayWidth = 320;
  814.         theDisplayHeight = 240;
  815.     }
  816. #endif
  817.         
  818.     /*
  819.     ** allocate an alt buffer that will be used for the underlay.  An
  820.     ** underlay is useful in games that have a need to restore from a
  821.     ** static background.
  822.     */
  823.     theError = DSpAltBuffer_New( theContext, false, 0, &theUnderlay );
  824.     if( theError )
  825.     {
  826.         DSpContext_Release( theContext );
  827.         ErrorMessage( "DSpAltBuffer_New (underlay)", theError );
  828.         return;
  829.     }
  830.     
  831.     theError = DSpContext_SetUnderlayAltBuffer( theContext, theUnderlay );
  832.     if( theError )
  833.     {
  834.         DSpContext_Release( theContext );
  835.         ErrorMessage( "DSpContext_SetUnderlayAltBuffer", theError );
  836.         return;
  837.     }
  838.     
  839. #if 0
  840.     /*
  841.     ** allocate an alt buffer that will be used as an overlay.  An overlay
  842.     ** is useful for things such as a cockpit view that is superimposed
  843.     ** on the back buffer before it is displayed.
  844.     */
  845.     if( inUseOverlay )
  846.     {
  847.         CGrafPtr theAltBufferPort;
  848.         GDHandle theAltBufferGDevice, theOldGDevice;
  849.         GrafPtr theOldPort;
  850.         
  851.         GetPort( &theOldPort );
  852.         theOldGDevice = GetGDevice();
  853.         
  854.         theError = DSpAltBuffer_New( theContext, false, 0, &theOverlay );
  855.         if( theError )
  856.         {
  857.             DSpContext_Release( theContext );
  858.             ErrorMessage( "DSpAltBuffer_New (overlay)", theError );
  859.             return;
  860.         }
  861.         
  862.         theError = DSpContext_SetOverlayAltBuffer( theContext, theOverlay );
  863.         if( theError )
  864.         {
  865.             DSpContext_Release( theContext );
  866.             ErrorMessage( "DSpContext_SetOverlayAltBuffer", theError );
  867.             return;
  868.         }
  869.  
  870.         /*
  871.         ** fill the overlay buffer with a pattern
  872.         */
  873.         theError = DSpAltBuffer_GetCGrafPtr( theOverlay,
  874.             kDSpBufferKind_Normal, &theAltBufferPort, &theAltBufferGDevice );
  875.         if( theError )
  876.         {
  877.             ErrorMessage( "DSpAltBuffer_GetCGrafPtr (overlay)", theError );
  878.             DSpContext_Release( theContext );
  879.             return;
  880.         }
  881.         
  882.         /*
  883.         ** if you want to use QuickDraw or any other toolbox rendering
  884.         ** code, you must setup the GDevice as well as the port when
  885.         ** working with AltBuffers!
  886.         */
  887.         SetPort( (GrafPtr)theAltBufferPort );
  888.         SetGDevice( theAltBufferGDevice );
  889.         
  890.         ForeColor( redColor );
  891.         TextSize(96);
  892.         MoveTo( 100, 200 );
  893.         DrawText( "Overlay!", 0, 8 );
  894.         
  895.         SetPort( theOldPort );
  896.         SetGDevice( theOldGDevice );
  897.     }
  898. #endif
  899.         
  900.     /*
  901.     ** If you are in a debug cycle, you may want to enable debugging mode
  902.     ** in DrawSprocket so that a fade out, followed by a break in the
  903.     ** debugger, won't leave you with nothing to see.
  904.     **
  905.     ** You can also create a folder in same folder as your game, and name
  906.     ** it "DSpSetDebugMode", this will also cause DSp to enter debug mode.
  907.     ** This method is handy if you don't want to rebuild your game with
  908.     ** the call just to debug it.
  909.     */
  910.     //DSpSetDebugMode( true );
  911.     
  912.     /*
  913.     ** fade out all displays to black, you must have at least one reserved
  914.     ** context to do this or you will get an error.  A game should always
  915.     ** fade to black before activating a context because if the activation
  916.     ** causes a resolution change the user will see a very ugly twitch in
  917.     ** the display.
  918.     */
  919.     theError = DSpContext_FadeGammaOut( NULL, NULL );
  920.     if( theError )
  921.     {
  922.         ErrorMessage( "DSpContext_FadeGammaOut", theError );
  923.         DSpContext_FadeGammaIn( NULL, NULL );
  924.         DSpContext_Release( theContext );
  925.         return;
  926.     }
  927.     
  928.     /* put the context into the active state */
  929.     theError = DSpContext_SetState( theContext, kDSpContextState_Active );
  930.     if( theError )
  931.     {
  932.         ErrorMessage( "DSpContext_SetState", theError );
  933.         DSpContext_FadeGammaIn( NULL, NULL );
  934.         DSpContext_Release( theContext );
  935.         return;
  936.     }
  937.  
  938.     /* fade back in */
  939.     theError = DSpContext_FadeGammaIn( NULL, NULL );
  940.     if( theError )
  941.     {
  942.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  943.         DSpContext_Release( theContext );
  944.         return;
  945.     }
  946.     
  947.     /*
  948.     ****************************************************************************
  949.     ** do the double buffering
  950.     ****************************************************************************
  951.     */
  952.     {    
  953.         UInt32 thePosition, theColorIndex, theXPos, theYPos;
  954.         CGrafPtr theAltBufferPort;
  955.         GDHandle theAltBufferGDevice, theOldGDevice;
  956.         Rect theRect;
  957.         GrafPtr theOldPort;
  958.         
  959.         GetPort( &theOldPort );
  960.         theOldGDevice = GetGDevice();
  961.         
  962.         /* set the alt buffer to be the current port */
  963.         theError = DSpAltBuffer_GetCGrafPtr( theUnderlay,
  964.             kDSpBufferKind_Normal, &theAltBufferPort, &theAltBufferGDevice );
  965.         if( theError )
  966.         {
  967.             ErrorMessage( "DSpAltBuffer_GetCGrafPtr (underlay)", theError );
  968.             DSpContext_FadeGammaIn( NULL, NULL );
  969.             DSpContext_Release( theContext );
  970.             return;
  971.         }
  972.         
  973.         /*
  974.         ** if you want to use QuickDraw or any other toolbox rendering
  975.         ** code, you must setup the GDevice as well as the port when
  976.         ** working with AltBuffers!
  977.         */
  978.         SetPort( (GrafPtr)theAltBufferPort );
  979.         SetGDevice( theAltBufferGDevice );
  980.  
  981.         /*
  982.         ** fill the underlay buffer with a pattern or clear it
  983.         */
  984.         if( inUseUnderlay )
  985.         {
  986.             /*
  987.             ** draw a pattern into the underlay buffer. this pattern will be
  988.             ** restored every time I get the back buffer
  989.             */
  990.             theColorIndex = 0;
  991.             for( theYPos = 0; theYPos < theDesiredAttributes.displayHeight;
  992.                 theYPos += kRectSize )
  993.             {
  994.                 for( theXPos = 0; theXPos < theDesiredAttributes.displayWidth;
  995.                     theXPos += kRectSize )
  996.                 {
  997.                     SetRect( &theRect, 0, 0, kRectSize, kRectSize );
  998.                     OffsetRect( &theRect, theXPos, theYPos );
  999.                     theAltBufferPort->fgColor = theColorIndex % 255;
  1000.                     
  1001.                     PaintRect( &theRect );
  1002.  
  1003.                     theColorIndex++;            
  1004.                 }
  1005.             }
  1006.         }
  1007.         else
  1008.         {
  1009.             ForeColor( blackColor );
  1010.             BackColor( whiteColor );
  1011.             SetRect( &theRect, 0, 0, theDesiredAttributes.displayWidth,
  1012.                 theDesiredAttributes.displayHeight );
  1013.             EraseRect( &theRect );
  1014.         }
  1015.             
  1016.         SetPort( theOldPort );
  1017.         SetGDevice( theOldGDevice );
  1018.     }
  1019.         
  1020.     /*
  1021.     ** this test slides a black vertical bar left and right on the
  1022.     ** display, producing an image where any tearing is amplified.
  1023.     */
  1024.     {
  1025.     
  1026.     RGBColor theColor, theTextColor;
  1027.     Rect theRectangleRect, theRect;
  1028.     UInt32 theStartTick, theMaxTick, theCurrentTick;
  1029.     UInt32 theCount, theRectangleDelta;
  1030.     UInt32 theWidth, theXPos, theYPos;
  1031.     CGrafPtr theBackBuffer;
  1032.     
  1033.     theColor.red = 0;
  1034.     theColor.green = 0;
  1035.     theColor.blue = 0;
  1036.     theTextColor.red = 0xFFFF;
  1037.     theTextColor.green = 0xFFFF;
  1038.     theTextColor.blue = 0xFFFF;
  1039.  
  1040.     /* rectangle will be 1/8 the display width, and all of the height */
  1041.     SetRect( &theRectangleRect, 0, 0, theDesiredAttributes.displayWidth >> 3,
  1042.         theDesiredAttributes.displayHeight );
  1043.     
  1044.     theStartTick = theCurrentTick = TickCount();
  1045.     theMaxTick = theStartTick + (15 * 60);
  1046.     theCount = 0;
  1047.     theRectangleDelta = 3;
  1048.     while( theCurrentTick < theMaxTick )
  1049.     {
  1050.         
  1051.         /* get the back buffer */
  1052.         theError = DSpContext_GetBackBuffer( theContext, kDSpBufferKind_Normal,
  1053.             &theBackBuffer );
  1054.         if( theError )
  1055.         {
  1056.             ErrorMessage( "DSpContext_GetBackBuffer", theError );
  1057.             DSpContext_Release( theContext );
  1058.             return;
  1059.         }
  1060.         
  1061.         /* set the back buffer to be the current port */
  1062.         SetPort( (GrafPtr)theBackBuffer );
  1063.         
  1064.         /* fill the display with a sliding vertical rectangle */
  1065.         RGBForeColor( &theColor );        
  1066.         PaintRect( &theRectangleRect );
  1067.  
  1068.         /* inval the new rect position */        
  1069.         theError = DSpContext_InvalBackBufferRect( theContext,
  1070.             &theRectangleRect );
  1071.             
  1072.         if( (theRectangleRect.right + theRectangleDelta) > theDesiredAttributes.displayWidth )
  1073.             theRectangleDelta = -theRectangleDelta;
  1074.         
  1075.         if ( (theRectangleRect.left + theRectangleDelta) < 0 )
  1076.             theRectangleDelta = -theRectangleDelta;
  1077.  
  1078.         theRectangleRect.left += theRectangleDelta;
  1079.         theRectangleRect.right += theRectangleDelta;
  1080.  
  1081.         // draw a frame counter
  1082.         sprintf((char *)&gTextBuffer[1],
  1083.             "This is frame %d (%d ticks remaining, %.1f fps)",
  1084.             theCount + 1, theMaxTick - theCurrentTick,
  1085.             (float)(theCount / ((theCurrentTick - theStartTick) / 60.0)) );
  1086.         gTextBuffer[0] = strlen( (char *)&gTextBuffer[1] );
  1087.         theWidth = StringWidth( (ConstStr255Param)gTextBuffer );
  1088.         theXPos = ( theDisplayWidth >> 1 ) - ( theWidth >> 1 );
  1089.         theYPos = theDisplayHeight - 20;
  1090.  
  1091.         theTextColor.red = 0;
  1092.         theTextColor.green = 0;
  1093.         theTextColor.blue = 0;
  1094.         RGBForeColor( &theTextColor );
  1095.         SetRect( &theRect, theXPos - 10, theYPos - 20, theXPos + theWidth + 10, theYPos + 10 );
  1096.         PaintRect( &theRect );
  1097.         
  1098.         theError = DSpContext_InvalBackBufferRect( theContext,
  1099.             &theRect );
  1100.  
  1101.         theTextColor.red = 0;
  1102.         theTextColor.green = 0xFFFF;
  1103.         theTextColor.blue = 0xFFFF;
  1104.         RGBForeColor( &theTextColor );
  1105.         FrameRect( &theRect );
  1106.         
  1107.         MoveTo( theXPos, theYPos );
  1108.         DrawString( (ConstStr255Param)gTextBuffer );
  1109.         
  1110.         // swap the buffers
  1111.         theError = DSpContext_SwapBuffers( theContext, NULL, 0 );
  1112.         if( theError )
  1113.         {
  1114.             ErrorMessage( "DSpContext_SwapBuffers", theError );
  1115.             DSpContext_Release( theContext );
  1116.             return;
  1117.         }
  1118.         
  1119.         /* increase frame counter */
  1120.         theCount++;
  1121.         theCurrentTick = TickCount();
  1122.     }
  1123.  
  1124.     }
  1125.     
  1126.     /*
  1127.     ****************************************************************************
  1128.     ** cleanup
  1129.     ****************************************************************************
  1130.     */    
  1131.  
  1132.     /* fade to black */
  1133.     theError = DSpContext_FadeGammaOut( NULL, NULL );
  1134.     if( theError )
  1135.     {
  1136.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1137.         DSpContext_Release( theContext );
  1138.         return;
  1139.     }
  1140.  
  1141.     /* remove the underlay & release it */
  1142.     DSpContext_SetUnderlayAltBuffer( theContext, NULL );
  1143.     DSpAltBuffer_Dispose( theUnderlay );
  1144.     theUnderlay = NULL;
  1145.     
  1146. #if 0
  1147.     /* remove the overlay & release it */
  1148.     if( inUseOverlay )
  1149.     {
  1150.         DSpContext_SetOverlayAltBuffer( theContext, NULL );
  1151.         DSpAltBuffer_Dispose( theOverlay );
  1152.         theOverlay = NULL;
  1153.     }
  1154. #endif
  1155.     
  1156.     /* put the context into the inactive state */
  1157.     theError = DSpContext_SetState( theContext, kDSpContextState_Inactive );
  1158.     if( theError )
  1159.     {
  1160.         ErrorMessage( "DSpContext_SetState", theError );
  1161.         DSpContext_FadeGammaIn( NULL, NULL );
  1162.         DSpContext_Release( theContext );
  1163.         return;
  1164.     }
  1165.  
  1166.     /* fade back in */
  1167.     theError = DSpContext_FadeGammaIn( NULL, NULL );
  1168.     if( theError )
  1169.     {
  1170.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1171.         DSpContext_Release( theContext );
  1172.         return;
  1173.     }
  1174.     
  1175.     /* release the context */
  1176.     theError = DSpContext_Release( theContext );
  1177.     if( theError )
  1178.     {
  1179.         ErrorMessage( "DSpContext_Release", theError );
  1180.         return;
  1181.     }
  1182. }
  1183.  
  1184. /*
  1185. ********************************************************************************
  1186. **
  1187. ** Name: TestContextCLUT
  1188. **
  1189. ** Description:
  1190. **
  1191. **    Test the ability of DrawSprocket to manipulate the CLUT.
  1192. **
  1193. ********************************************************************************
  1194. */
  1195. void TestContextCLUT( void )
  1196. {
  1197.     DSpContextAttributes theDesiredAttributes;
  1198.     DSpContextReference theContext;
  1199.     OSStatus theError;
  1200.     RGBColor theBlankingColor;
  1201.     
  1202.     printf("\n\n");
  1203.     printf("############################################################\n");
  1204.     printf("###                     Testing CLUT                     ###\n");
  1205.     printf("############################################################\n");
  1206.     printf("\n\n");
  1207.  
  1208.  
  1209.     /* find the context */
  1210.     MyInitAttributes( &theDesiredAttributes );
  1211.     theDesiredAttributes.displayWidth            = 640;
  1212.     theDesiredAttributes.displayHeight            = 480;
  1213.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  1214.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  1215.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  1216.     theDesiredAttributes.backBufferBestDepth    = 8;
  1217.     theDesiredAttributes.displayBestDepth        = 8;
  1218.     theDesiredAttributes.pageCount                = 2;
  1219.     theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
  1220.     if( theError && kDSpContextNotFoundErr != theError )
  1221.     {
  1222.         ErrorMessage( "DSpFindBestContext", theError );
  1223.         return;
  1224.     }
  1225.     if( kDSpContextNotFoundErr == theError )
  1226.     {
  1227.         printf("# Unable to find a matching context for the following attributes:\n");
  1228.         DumpContextAttributes( &theDesiredAttributes );
  1229.         return;
  1230.     }
  1231.  
  1232.     /* reserve the context */    
  1233.     theError = DSpContext_Reserve( theContext, &theDesiredAttributes );
  1234.     if( theError )
  1235.     {
  1236.         ErrorMessage( "DSpContext_Reserve", theError );
  1237.         return;
  1238.     }
  1239.  
  1240.     /* set the blanking color to white, just for the heck of it */
  1241.     theBlankingColor.red = 0xFFFFF;    
  1242.     theBlankingColor.green = 0xFFFFF;    
  1243.     theBlankingColor.blue = 0xFFFFF;    
  1244.     theError = DSpSetBlankingColor( &theBlankingColor );
  1245.     if( theError )
  1246.     {
  1247.         ErrorMessage( "DSpSetBlankingColor", theError );
  1248.         return;
  1249.     }
  1250.  
  1251.     /* fade out all displays to black */
  1252.     theError = DSpContext_FadeGammaOut( NULL, NULL );
  1253.     if( theError )
  1254.     {
  1255.         ErrorMessage( "DSpContext_FadeGammaOut", theError );
  1256.         DSpContext_FadeGammaIn( NULL, NULL );
  1257.         DSpContext_Release( theContext );
  1258.         return;
  1259.     }
  1260.     
  1261.     /* put the context into the active state */
  1262.     theError = DSpContext_SetState( theContext, kDSpContextState_Active );
  1263.     if( theError )
  1264.     {
  1265.         ErrorMessage( "DSpContext_SetState", theError );
  1266.         DSpContext_FadeGammaIn( NULL, NULL );
  1267.         DSpContext_Release( theContext );
  1268.         return;
  1269.     }
  1270.  
  1271.     /* fade back in */
  1272.     theError = DSpContext_FadeGammaIn( NULL, NULL );
  1273.     if( theError )
  1274.     {
  1275.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1276.         DSpContext_Release( theContext );
  1277.         return;
  1278.     }
  1279.     
  1280.     /*
  1281.     ****************************************************************************
  1282.     ** do the CLUT testing
  1283.     ****************************************************************************
  1284.     */
  1285.     
  1286.     /* draw a pattern into the back buffer and cycle it */
  1287.     {
  1288.     UInt32 thePosition, theColorIndex, theXPos, theYPos;
  1289.     CGrafPtr theBackBuffer;
  1290.     ColorSpec theOriginalColors[256];
  1291.     Rect theRect;
  1292.     
  1293.     /* get the back buffer */
  1294.     theError = DSpContext_GetBackBuffer( theContext, kDSpBufferKind_Normal,
  1295.         &theBackBuffer );
  1296.     if( theError )
  1297.     {
  1298.         ErrorMessage( "DSpContext_GetBackBuffer", theError );
  1299.         DSpContext_Release( theContext );
  1300.         return;
  1301.     }
  1302.     
  1303.     /* set the back buffer to be the current port */
  1304.     SetPort( (GrafPtr)theBackBuffer );
  1305.  
  1306.     /* draw a pattern into the back buffer */
  1307.     theColorIndex = 0;
  1308.     for( theYPos = 0; theYPos < theDesiredAttributes.displayHeight;
  1309.         theYPos += kRectSize )
  1310.     {
  1311.         for( theXPos = 0; theXPos < theDesiredAttributes.displayWidth;
  1312.             theXPos += kRectSize )
  1313.         {
  1314.             Rect theRect;
  1315.             
  1316.             SetRect( &theRect, 0, 0, kRectSize, kRectSize );
  1317.             OffsetRect( &theRect, theXPos, theYPos );
  1318.             theBackBuffer->fgColor = theColorIndex % 255;
  1319.             
  1320.             PaintRect( &theRect );
  1321.  
  1322.             theColorIndex++;            
  1323.         }
  1324.     }
  1325.     
  1326.     /* bring the back buffer to the front */
  1327.     theError = DSpContext_SwapBuffers( theContext, NULL, 0 );
  1328.     if( theError )
  1329.     {
  1330.         ErrorMessage( "DSpContext_SwapBuffers", theError );
  1331.         DSpContext_Release( theContext );
  1332.         return;
  1333.     }
  1334.     
  1335.     /*
  1336.     ** get the original color table
  1337.     **
  1338.     ** unfortunately, these probably aren't the real colors, since
  1339.     ** the way that gamma works on the Mac is to remap the indexed
  1340.     ** color table to new colors.  In other words, these colors are
  1341.     ** gamma corrected versions of the ones that were originally set.
  1342.     **
  1343.     */
  1344.     theError = DSpContext_GetCLUTEntries( theContext, theOriginalColors,
  1345.         0, 255 );
  1346.     if( theError )
  1347.     {
  1348.         ErrorMessage( "DSpContext_GetCLUTEntries", theError );
  1349.         DSpContext_Release( theContext );
  1350.         return;
  1351.     }
  1352.     
  1353.     /* cycle the colors */
  1354.     while( !Button() )
  1355.     {
  1356.         ColorSpec theSpec[256], theTempSpec;
  1357.         
  1358.         /* rotate them */
  1359.         theTempSpec = theOriginalColors[0];
  1360.         
  1361.         for( theColorIndex = 0; theColorIndex < 255; theColorIndex++ )
  1362.             theSpec[theColorIndex].rgb =
  1363.                 theOriginalColors[(theColorIndex + thePosition) % 255].rgb;
  1364.  
  1365.         theSpec[255].rgb = theTempSpec.rgb;
  1366.         
  1367.         thePosition++;
  1368.         if( thePosition > 255 )
  1369.             thePosition = 0;
  1370.         
  1371.         /* set the entries */
  1372.         theError = DSpContext_SetCLUTEntries( theContext, theSpec, 0, 255 );
  1373.         if( theError )
  1374.         {
  1375.             ErrorMessage( "DSpContext_SetCLUTEntries", theError );
  1376.             DSpContext_Release( theContext );
  1377.             return;
  1378.         }
  1379.     }
  1380.  
  1381.     }
  1382.     
  1383.     /*
  1384.     ****************************************************************************
  1385.     ** cleanup
  1386.     ****************************************************************************
  1387.     */    
  1388.  
  1389.     /* fade to black */
  1390.     theError = DSpContext_FadeGammaOut( NULL, NULL );
  1391.     if( theError )
  1392.     {
  1393.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1394.         DSpContext_Release( theContext );
  1395.         return;
  1396.     }
  1397.  
  1398.     /* put the context into the inactive state */
  1399.     theError = DSpContext_SetState( theContext, kDSpContextState_Inactive );
  1400.     if( theError )
  1401.     {
  1402.         ErrorMessage( "DSpContext_SetState", theError );
  1403.         DSpContext_FadeGammaIn( NULL, NULL );
  1404.         DSpContext_Release( theContext );
  1405.         return;
  1406.     }
  1407.  
  1408.     /* fade back in */
  1409.     theError = DSpContext_FadeGammaIn( NULL, NULL );
  1410.     if( theError )
  1411.     {
  1412.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1413.         DSpContext_Release( theContext );
  1414.         return;
  1415.     }
  1416.     
  1417.     /* release the context */
  1418.     theError = DSpContext_Release( theContext );
  1419.     if( theError )
  1420.     {
  1421.         ErrorMessage( "DSpContext_Release", theError );
  1422.         return;
  1423.     }
  1424. }
  1425.  
  1426. void
  1427. TestUserSelectContext( void )
  1428. {
  1429.     DSpContextAttributes theDesiredAttributes;
  1430.     DSpContextAttributes theActualAttributes;
  1431.     DSpContextReference theContext;
  1432.     OSStatus theError;
  1433.     RGBColor theBlankingColor;
  1434.     Boolean theShowDialogFlag;
  1435.     DisplayIDType theDisplayID;
  1436.     
  1437.     printf("\n\n");
  1438.     printf("############################################################\n");
  1439.     printf("###                     Testing CLUT                     ###\n");
  1440.     printf("############################################################\n");
  1441.     printf("\n\n");
  1442.  
  1443.  
  1444.     /* find the context */
  1445.     MyInitAttributes( &theDesiredAttributes );
  1446.     theDesiredAttributes.displayWidth            = 640;
  1447.     theDesiredAttributes.displayHeight            = 480;
  1448.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  1449.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  1450.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  1451.     theDesiredAttributes.backBufferBestDepth    = 8;
  1452.     theDesiredAttributes.displayBestDepth        = 8;
  1453.     theDesiredAttributes.pageCount                = 2;
  1454.  
  1455.     /*
  1456.     ** see if there are enough choices available for the user to
  1457.     ** choose from, this can be used if I needed to determine
  1458.     ** whether or not to enable a menu item, etc.
  1459.     */
  1460.     theError = DSpCanUserSelectContext( &theDesiredAttributes,
  1461.         &theShowDialogFlag );
  1462.     if( theError )
  1463.     {
  1464.         ErrorMessage( "DSpCanUserSelectContext", theError );
  1465.         return;
  1466.     }
  1467.     if( false == theShowDialogFlag )
  1468.     {
  1469.         printf("There are not enough choices to warrant asking the user.\n");
  1470.         return;
  1471.     }
  1472.     
  1473.     /*
  1474.     ** put up the choice dialog, I don't care about what display it
  1475.     ** appears on, nor do I care to know about update events
  1476.     */
  1477.     theError = DSpUserSelectContext( &theDesiredAttributes, 0,
  1478.         NULL, &theContext );
  1479.     if( theError )
  1480.     {
  1481.         /*
  1482.         ** since we know that there were possible matches available (because
  1483.         ** we called DSpCanUserSelectContext), we know that a context-not-found
  1484.         ** error means that the user canceled the dialog
  1485.         */
  1486.         if( kDSpContextNotFoundErr == theError )
  1487.             printf("The user canceled the dialog.\n");
  1488.         else
  1489.             ErrorMessage( "DSpUserSelectContext", theError );
  1490.         return;
  1491.     }
  1492.  
  1493.     /* tell the user about the results */
  1494.     printf("User-Selected Context for the following attributes...\n");
  1495.     DumpContextAttributes( &theDesiredAttributes );
  1496.     
  1497.     theError = DSpContext_GetDisplayID( theContext, &theDisplayID );
  1498.     if( theError )
  1499.     {
  1500.         ErrorMessage( "DSpContext_GetDisplayID", theError );
  1501.         return;
  1502.     }
  1503.  
  1504.     theError = DSpContext_GetAttributes( theContext, &theActualAttributes );
  1505.     if( theError )
  1506.     {
  1507.         ErrorMessage( "DSpContext_GetAttributes", theError );
  1508.         return;
  1509.     }
  1510.  
  1511.     printf("...is the context on display id %d with these attributes:\n",
  1512.         theDisplayID );
  1513.     DumpContextAttributes( &theActualAttributes );
  1514. }
  1515.